/**
 * Copyright (c) 2018-2023, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: atomic for riscv64
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2023-08-24     JasonHu           Init
 */

#include <nxos/atomic.h>

void NX_AtomicSet(NX_Atomic *atomic, NX_AtomicValue value)
{
    atomic->value = value;
}

NX_AtomicValue NX_AtomicGet(NX_Atomic *atomic)
{
    return atomic->value;
}

void NX_AtomicAdd(NX_Atomic *atomic, NX_AtomicValue value)
{
    /* gcc build-in functions */
    atomic->value += value;
}

void NX_AtomicSub(NX_Atomic *atomic, NX_AtomicValue value)
{
    atomic->value -= value;
}

void NX_AtomicInc(NX_Atomic *atomic)
{
    atomic->value += 1;
}

void NX_AtomicDec(NX_Atomic *atomic)
{
    atomic->value -= 1;
}

void NX_AtomicSetMask(NX_Atomic *atomic, NX_AtomicValue mask)
{
    atomic->value |= mask;
}

void NX_AtomicClearMask(NX_Atomic *atomic, NX_AtomicValue mask)
{    
    atomic->value &= ~mask;
}

NX_AtomicValue NX_AtomicSwap(NX_Atomic *atomic, NX_AtomicValue newValue)
{
    long old = atomic->value;
    atomic->value = newValue;

    return old;
}

NX_AtomicValue NX_AtomicCAS(NX_Atomic *atomic, NX_AtomicValue old, NX_AtomicValue newValue)
{
    long _old = atomic->value;
    if (_old == old)
    {
        atomic->value = newValue;
    }
    return _old;
}
